package models

import (
	"time"
	"path"
	"github.com/UnKnwon/com"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"os"
	"strconv"
	"strings"
)

const (
	DB_UAER     = "root"
	DB_PASSWORD = "root"
	DB          = "data"
)

/**
分类
 */
type Category struct {
	Id              int64                        //id 类型为int64和int32时自动设置为主键
	Title           string                       //标题
	Created         time.Time `orm:"index;null"` //创建时间
	Views           int64     `orm:"index;null"` //浏览时间
	TopicTime       time.Time `orm:"index;null"` //标题创建的时间
	TopicCount      int64                        //数量
	TopicLastUserId int64                        //最后浏览的人
}

/**
文章
 */
type Topic struct {
	Id              int64
	Uid             int64
	Category        string
	Title           string
	Labels          string //标签
	Content         string    `orm:"size(5000)"`
	Attachment      string
	Created         time.Time `orm:"index;null"`
	Updated         time.Time `orm:"index;null"`
	Views           int64     `orm:"index;null"`
	Author          string
	ReplyTime       time.Time `orm:"index;null"`
	ReplyCount      int64
	ReplyLastUserId int64
}

/**
评论
 */
type Comment struct {
	Id      int64
	Tid     int64
	Name    string
	Content string    `orm:size(6000)`
	Create  time.Time `orm:index`
}

func RegisterDB() {
	//当数据库不存在时，人为的去创建数据库
	if com.IsExist(DB_UAER) {
		os.MkdirAll(path.Dir(DB_UAER), os.ModePerm)
		os.Create(DB_UAER)
	}

	//注册模型
	orm.RegisterModel(new(Category), new(Topic), new(Comment))
	//注册驱动
	orm.RegisterDriver("mysql", orm.DRMySQL)
	//数据类型
	conn := DB_UAER + ":" + DB_PASSWORD + "@/" + DB + "?charset=utf8"
	err := orm.RegisterDataBase("default", "mysql", conn)
	if err != nil {
		panic(err)
	}
}

/**
添加标题的名字
 */
func AddCategory(name string) error {
	o := orm.NewOrm()

	cate := &Category{Title: name}

	/*qs := o.QueryTable("category")
	err := qs.Filter("title",name).One(cate)
	if err == nil{
		return err
	}*/

	_, err := o.Insert(cate)
	if err != nil {
		return err
	}

	return nil
}

/**
获取所有的分类内容
 */
func GetAllCategorier() ([]*Category, error) {
	o := orm.NewOrm()
	cates := make([]*Category, 0)
	qs := o.QueryTable("category")
	_, err := qs.All(&cates)
	return cates, err

}

/**
删除Category的id
 */
func DeleteCategory(id string) error {
	ids, err := strconv.ParseInt(id, 10, 64)
	if err != nil {
		return nil
	}
	o := orm.NewOrm()
	cate := &Category{Id: ids}
	_, err = o.Delete(cate)
	return err
}

/**
添加topic的标题和内容
 */
func AddTopic(title, content string, category string, label string) error {
	//处理标签
	//bee go
	//bee#$go
	//$bee#$go#
	label = "$" + strings.Join(strings.Split(label, ""), "#$") + "#"

	o := orm.NewOrm()
	topic := &Topic{
		Title:    title,
		Category: category,
		Content:  content,
		Labels:   label,
		Created:  time.Now(),
		Updated:  time.Now(),
	}
	_, err := o.Insert(topic)
	if err != nil {
		return err
	}

	//更新分类统计
	cate := new(Category)
	qs := o.QueryTable("category")
	err = qs.Filter("title", category).One(cate)
	if err == nil {
		//如果不存在，简单的忽略更新操作
		cate.TopicCount++
		_, err = o.Update(cate)
	}
	return err
}

/**
   isDesc:是否倒序
 */
func GetAllTopics(cate string, isDesc bool) ([]*Topic, error) {
	o := orm.NewOrm()
	topics := make([]*Topic, 0)
	qs := o.QueryTable("topic")

	var err error
	if isDesc {
		if len(cate) > 0 {
			qs = qs.Filter("category", cate)
		}
		_, err = qs.OrderBy("-created").All(&topics)
	} else {
		_, err = qs.All(&topics)
	}

	return topics, err

}

/**
获取topic的id
 */
func GetTopic(tid string) (*Topic, error) {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return nil, err
	}

	o := orm.NewOrm()

	topic := new(Topic)

	qs := o.QueryTable("topic")
	err = qs.Filter("id", tidNum).One(topic)
	if err != nil {
		return nil, err
	}

	topic.Views++
	_, err = o.Update(topic)

	//将#$的格式变回去
	topic.Labels = strings.Replace(strings.Replace(topic.Labels,"#","",-1),"$","",-1)
	return topic, err
}

/**
修改文章
 */

func ModifyTopic(tid, title, content string, category string,lable string) error {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return err
	}

	o := orm.NewOrm()

	var oldCate string

	//在read之前如果有匹配的非零值，会根据这个修改
	lable = "$" + strings.Join(strings.Split(lable, ""), "#$") + "#"
	topic := &Topic{Id: tidNum}
	if o.Read(topic) == nil {
		oldCate = topic.Category
		topic.Title = title
		topic.Labels = lable
		topic.Category = category
		topic.Content = content
		topic.Updated = time.Now()
		o.Update(topic)
	}

	//更新分类统计
	if len(oldCate) > 0 {
		cate := new(Category)
		qs := o.QueryTable("category")
		err := qs.Filter("title", oldCate).One(cate)
		if err == nil {
			cate.TopicCount--
			_, err = o.Update(cate)
		}
	}

	cate := new(Category)
	qs := o.QueryTable("category")
	err = qs.Filter("title", category).One(cate)
	if err == nil {
		cate.TopicCount++
		_, err = o.Update(cate)
	}
	return err
}

/**
删除文章
 */
func DeleteTopic(tid string) error {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return err
	}

	var oldCate string

	o := orm.NewOrm()
	topic := &Topic{Id: tidNum}
	if o.Read(topic) == nil {
		oldCate = topic.Category
		_, err = o.Delete(topic)
		if err != nil {
			return nil
		}
	}

	if len(oldCate) > 0 {
		cate := new(Category)
		qs := o.QueryTable("category")
		qs.Filter("title", oldCate).One(cate)
		if err == nil {
			cate.TopicCount--
			_, err = o.Update(cate)
		}
	}
	_, err = o.Delete(topic)

	return err
}

/**
增加评论
 */
func AddReplay(tid, name, content string) error {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return err
	}

	o := orm.NewOrm()
	comment := &Comment{
		Tid:     tidNum,
		Name:    name,
		Content: content,
		Create:  time.Now(),
	}
	_, err = o.Insert(comment)
	if err != nil {
		return err
	}

	//增加回复数
	topic := &Topic{Id: tidNum}
	if o.Read(topic) == nil {
		topic.ReplyTime = time.Now()
		topic.ReplyCount++
		_, err = o.Update(topic)
	}

	return err
}

/**
根据tid查询全部
 */
func QueryReplay(tid string) (replay []*Comment, err error) {
	tidNum, _ := strconv.ParseInt(tid, 10, 64)

	o := orm.NewOrm()
	replay = make([]*Comment, 0)
	qs := o.QueryTable("comment")
	qs.Filter("tid", tidNum).All(&replay)

	return replay, err

}

/**
删除评论
 */
func DeleteReplay(id string) error {
	rid, err := strconv.ParseInt(id, 10, 64)
	if err != nil {
		return err
	}

	o := orm.NewOrm()
	var tidNum int64
	comment := &Comment{Id: rid}
	if o.Read(comment) == nil {
		tidNum = comment.Tid
		_, err = o.Delete(comment)
		if err != nil {
			return err
		}
	}

	//删除回复统计（有待研究）
	replies := make([]*Comment, 0)
	qs := o.QueryTable("comment")
	_, err = qs.Filter("tid", tidNum).OrderBy("-create").All(&replies)
	if err != nil {
		return err
	}

	topic := &Topic{Id: tidNum}
	if o.Read(topic) == nil {
		//topic.ReplyTime = replies[0].Create
		topic.ReplyCount = int64(len(replies))
		_, err = o.Update(topic)
	}
	return err
}
